package managerEngine

import (
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"net/url"
	"strconv"
	"time"

	"gitee.com/RocsSun/report/config"
	"github.com/go-resty/resty/v2"
	"gopkg.in/yaml.v2"
)

type NetFlowSpider struct {
}

// var NetFlowSpider *NetFlowSpider

func NewNetFlowSpider() *NetFlowSpider {
	return &NetFlowSpider{}
}

func (n *NetFlowSpider) Login(username, password string) bool {
	// 获取JSESSIONID
	NetFlowAnalyzer := config.ConfigContext.ManagerEngine.NetFlowAnalyzer
	urlBaseURL, err := url.ParseRequestURI(NetFlowAnalyzer.URI.BaseURL)
	if err != nil {
		log.Fatal(err)
		return false
	}
	_, err = Spider.R().Get(NetFlowAnalyzer.URI.BaseURL + NetFlowAnalyzer.URI.BaseURL)
	if err != nil {
		log.Fatal(err)
		return false
	}

	// ServerLet
	param := map[string]string{
		"readAutoLoginCookie": "true",
		"eraseCookie":         "true",
		"cookieName":          "f2RedirectUrl",
	}
	_, err = Spider.R().SetCookies(Jar.Cookies(urlBaseURL)).SetFormData(param).Post(
		NetFlowAnalyzer.URI.BaseURL + NetFlowAnalyzer.URI.ServerLet,
	)
	if err != nil {
		log.Fatal(err)
		return false
	}
	param = map[string]string{
		"GetLoginAd":       "UNITED STATES OF AMERICA",
		"cookieUpdate":     "true",
		"cookieName":       "CountryName",
		"cookieValue":      "UNITED STATES OF AMERICA",
		"cookieExpiry":     "30",
		"WebConsoleOpened": "Yes",
	}
	_, err = Spider.R().SetCookies(Jar.Cookies(urlBaseURL)).SetFormData(param).Post(
		NetFlowAnalyzer.URI.BaseURL + NetFlowAnalyzer.URI.ServerLet,
	)
	if err != nil {
		log.Fatal(err)
		return false
	}

	rand.Seed(time.Now().UnixNano())
	params := map[string]string{
		"requestType": "AJAX",
		"sid":         strconv.FormatFloat(rand.Float64(), 'G', 17, 64),
	}

	data := map[string]string{
		"signInAutomatically": "true",
	}

	_, err = Spider.R().SetCookies(Jar.Cookies(urlBaseURL)).SetQueryParams(params).SetFormData(data).Post(
		NetFlowAnalyzer.URI.BaseURL + NetFlowAnalyzer.URI.ServerLet,
	)
	if err != nil {
		log.Fatal(err)
		return false
	}

	// j security check
	jSecurityCheckURL := NetFlowAnalyzer.URI.BaseURL + "j_security_check;"
	for _, v := range Jar.Cookies(urlBaseURL) {
		if v.Name == "JSESSIONID" {
			jSecurityCheckURL += "jsessionid=" + v.Value
		}
	}
	data = map[string]string{
		"AUTHRULE_NAME":       "Authenticator",
		"clienttype":          "html",
		"ScreenWidth":         "2000",
		"ScreenHeight":        "1051",
		"loginFromCookieData": "false",
		"ntlmv2":              "false",
		"j_username":          "admin",
		"j_password":          "admin",
		"signInAutomatically": "on",
		"uname":               "",
	}
	_, err = Spider.R().SetCookies(Jar.Cookies(urlBaseURL)).SetFormData(data).Post(jSecurityCheckURL)
	if err != nil {
		log.Fatal(err)
		return false
	}
	// 更新全局cookies
	Spider.SetCookies(Jar.Cookies(urlBaseURL))
	err = n.SerializerCookies(NetFlowAnalyzer.CookiesPath, Jar.Cookies(urlBaseURL))
	return err == nil
}

// SerializerCookies Cookies持久化
func (n *NetFlowSpider) SerializerCookies(filepath string, cookie []*http.Cookie) error {
	cookieBytes, err := yaml.Marshal(cookie)
	if err != nil {
		return err
	}
	return ioutil.WriteFile(filepath, cookieBytes, 0776)
}

// UnSerializerCookies 反序列化
func (n *NetFlowSpider) UnSerializerCookies(filePath string) ([]*http.Cookie, error) {
	fileBytes, err := ioutil.ReadFile(filePath)
	if err != nil {
		return nil, err
	}
	cookies := make([]*http.Cookie, 10)
	if err = yaml.Unmarshal(fileBytes, &cookies); err != nil {
		return nil, err
	}
	return cookies, nil
}

func (n *NetFlowSpider) GetNetWorkData(url string, params *map[string]string) (*resty.Response, error) {
	return Spider.R().SetPathParams(*params).Get(url)
}
